// 《围棋》作者版权所有。保留所有权利。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package runtime

import "unsafe"

// 该文件处理来自系统调用包
// 的一些系统调用，forkAndExecInChild期间使用的系统调用不能拆分堆栈

// go:cgo_import_dynamic libc_chdir chdir“libc.a/shr_64.o”
// go:cgo_import_dynamic libc_chroot chroot”libc.a/shr_64.o“
// go:cgo_import_dynamic libc_dup2; dup2 libc.a/shr_64.o”
// go：

// go:linkname libc_execve libc_execve 
// go:linkname libc_fcntl libc_fcntl libc_fcntl 
// go:linkname libc_fork libc_fork libc_fork 
// go go linkname libc_ioctl libc_ioctl libc_ioctl 
// go go go go linkname libc_setgid libc_setgid libc_setgid 
// go:linkname libc_setpgid libc_setpgid 

var (
	libc_chdir,
	libc_chroot,
	libc_dup2,
	libc_execve,
	libc_fcntl,
	libc_fork,
	libc_ioctl,
	libc_setgid,
	libc_setgroups,
	libc_setsid,
	libc_setuid,
	libc_setpgid libFunc
)

// 在syscall_syscall6和syscall_rawsyscall6中，r2始终是0 
// 因为它从未在AIX上使用过
// TODO:从zsyscall_AIX_$GOARCH中删除r2。go 

// 需要Syscall，因为有些软件包（比如net）也需要它。
// 最好的方法是返回EINVAL并让Golang处理其失败
// 如果系统调用不能失败，此函数可以将其重定向到真正的系统调用。
// 
// 这是通过linkname导出到syscall包中的程序集的。
// 
// go:nosplit 
// go:linkname syscall_syscall 
func syscall_Syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
	return 0, 0, _EINVAL
}

// 这是syscall。RawSyscall，它的存在是为了满足一些构建依赖关系，
// 但它不起作用。
// 
// 这是通过linkname导出到syscall包中的程序集的。
// 
// go:linkname syscall_RawSyscall 
func syscall_RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
	panic("RawSyscall not available on AIX")
}

// 这是通过linkname导出到syscall包中的程序集的。
// 
// go:nosplit 
// go:cgo_unsafe_args 
// go:linkname syscall_syscall6 
func syscall_syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
	c := libcall{
		fn:   fn,
		n:    nargs,
		args: uintptr(unsafe.Pointer(&a1)),
	}

	entersyscallblock()
	asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c))
	exitsyscall()
	return c.r1, 0, c.err
}

// 这是通过linkname导出到syscall包中的程序集的。
// 
// go:nosplit 
// go:cgo_unsafe_args 
// go:linkname syscall_rawSyscall6 
func syscall_rawSyscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
	c := libcall{
		fn:   fn,
		n:    nargs,
		args: uintptr(unsafe.Pointer(&a1)),
	}

	asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(&c))

	return c.r1, 0, c.err
}

// go linkname syscall_chdir syscall。chdir 
// go:nosplit 
func syscall_chdir(path uintptr) (err uintptr) {
	_, err = syscall1(&libc_chdir, path)
	return
}

// go:linkname syscall_chroot1 syscall。chroot1 
// go:nosplit 
func syscall_chroot1(path uintptr) (err uintptr) {
	_, err = syscall1(&libc_chroot, path)
	return
}

// 类似于close，但不能拆分堆栈，例如fork。
// go:linkname syscall\u close syscall。关闭
// go:nosplit 
func syscall_close(fd int32) int32 {
	_, err := syscall1(&libc_close, uintptr(fd))
	return int32(err)
}

// go:linkname syscall_dup2child syscall。dup2child 
// go:nosplit 
func syscall_dup2child(old, new uintptr) (val, err uintptr) {
	val, err = syscall2(&libc_dup2, old, new)
	return
}

// go:linkname syscall_execve syscall。execve-
// go:nosplit-
func syscall_execve(path, argv, envp uintptr) (err uintptr) {
	_, err = syscall3(&libc_execve, path, argv, envp)
	return
}

// like exit，但对于fork，不能拆分堆栈。
// go:linkname syscall_exit syscall。退出
// go:nosplit 
func syscall_exit(code uintptr) {
	syscall1(&libc_exit, code)
}

// go:linkname syscall\u fcntl1 syscall。fcntl1 
// go:nosplit 
func syscall_fcntl1(fd, cmd, arg uintptr) (val, err uintptr) {
	val, err = syscall3(&libc_fcntl, fd, cmd, arg)
	return

}

// go:linkname syscall_forkx syscall。forkx 
// go:nosplit 
func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) {
	pid, err = syscall1(&libc_fork, flags)
	return
}

// go:linkname syscall_getpid syscall。getpid 
// go:nosplit 
func syscall_getpid() (pid, err uintptr) {
	pid, err = syscall0(&libc_getpid)
	return
}

// go:linkname syscall_ioctl syscall。ioctl 
// go:nosplit 
func syscall_ioctl(fd, req, arg uintptr) (err uintptr) {
	_, err = syscall3(&libc_ioctl, fd, req, arg)
	return
}

// go:linkname syscall_setgid syscall。setgid 
// go:nosplit 
func syscall_setgid(gid uintptr) (err uintptr) {
	_, err = syscall1(&libc_setgid, gid)
	return
}

// go:linkname syscall_setgroups1 syscall。setgroups1 
// go:nosplit 
func syscall_setgroups1(ngid, gid uintptr) (err uintptr) {
	_, err = syscall2(&libc_setgroups, ngid, gid)
	return
}

// go:linkname syscall_setsid syscall。setsid 
// go:nosplit 
func syscall_setsid() (pid, err uintptr) {
	pid, err = syscall0(&libc_setsid)
	return
}

// go:linkname syscall_setuid syscall。setuid 
// go:nosplit 
func syscall_setuid(uid uintptr) (err uintptr) {
	_, err = syscall1(&libc_setuid, uid)
	return
}

// go:linkname syscall_setpgid syscall。setpgid 
// go:nosplit 
func syscall_setpgid(pid, pgid uintptr) (err uintptr) {
	_, err = syscall2(&libc_setpgid, pid, pgid)
	return
}

// go:linkname syscall_write1 syscall。write1 
// go:nosplit 
func syscall_write1(fd, buf, nbyte uintptr) (n, err uintptr) {
	n, err = syscall3(&libc_write, fd, buf, nbyte)
	return
}
